﻿using System;
using System.Diagnostics;
using Crowler.Model.CoreComponents;
using Crowler.Model.CoreComponents.DataAccess;

namespace CoreComponents
{
    public class BusinessServiceFacility<TRequest, TResponse, TRequestDest, TResponseDest> : 
        IBusinessServiceFacility<TRequest, TResponse, TRequestDest, TResponseDest> where TRequestDest : class where TResponse : class
    {
        private readonly IDataAccessManager _dataAccessManager;
        private readonly IAppEnvironment _appEnv;
        public TRequest Request { set; private get; }
        public TResponse Response { private set; get; }
        public string ServiceName { get; set; }
        public BusinessServiceFacility(IAppEnvironment appEnv)
        {
            _appEnv = appEnv;
            _dataAccessManager = appEnv.Resolve<IDataAccessManager>();
        }

        public void Execute()
        {
            try
            {
                var service = string.IsNullOrEmpty(ServiceName) ?
                    _appEnv.Resolve<IBusinessService<TRequestDest, TResponseDest>>() :
                    _appEnv.Resolve<IBusinessService<TRequestDest, TResponseDest>>(ServiceName);
                service.ServiceRequest = Request as TRequestDest;
                service.InitializeDefaultResponse();
                InnerWraper(service);
                Response = service.ServiceResponse as TResponse;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                //TODO write to log e
            }
        }

        private void InnerWraper(IBusinessService<TRequestDest, TResponseDest> service)
        {
            using (var uow = _dataAccessManager.Start())
            {
                try
                {
                    service.Execute();
                }
                catch (Exception)
                {
                    uow.IsExecutionException = true;
                }
            }
        }
    }
}
